# ======================================================================
#
# Copyright (C) ADN
# ADN::LIBRARY::TELNET::ClientTEL
# Description:
#  - Client TELNET
#  - TELNET client
#
# ======================================================================

package ADN::LIBRARY::TELNET::ClientTEL;

use strict;
use Time::HiRes qw(sleep);
use Net::Telnet;
use ADN::LOG::Log;
use ADN::LANG::Lang;

# #######################
# CREATE OBJECT
# #######################
sub new {
	# Construction de l'objet $self
	my $self = shift;
	my $class = ref($self) || $self;
	return $self if ref $self;
	$self = bless {} => $class;
  $self->{telnet} = Net::Telnet->new(Host    => $_[0],
                                     Timeout => 10,
						                         Errmode => 'return');
  $self->{lines} = '';
  $self->{return} = '';
  $self->{HOST} = $_[0];
  $self->{log} = ADN::LOG::Log->new();
  %{$self->{lang}} = ADN::LANG::Lang->new()->telnet();
  if (!defined $self->{telnet})
  {
    $self->{log}->Log( $self->{lang}{mess1}.$_[0], 2, 5 );
    return undef;
  }
  $self->{log}->Log( $self->{lang}{mess2}.$_[0], 1, 5 );
	return $self;
}

# #######################
# SEND
# #######################
sub send
{
  my $self = shift;
  $self->{return} = "";

  if (defined $self->{telnet})
  {
      $self->{log}->Log( $self->{lang}{mess5}.'"'.$_[0].'"', 1, 5 );
      $self->{telnet}->print($_[0]);
      sleep $_[1] if (defined $_[1]);
  }
  return;
}

# #######################
# GET LAST LINE
# #######################
sub get_lastline
{
  my $self = shift;
  my ($get);

  if (defined $self->{telnet})
  {
    sleep $_[0] if (defined $_[0]);
    $get = $self->{telnet}->get();
    if ($get) {
      $self->{lines} .= $get;
      $get =~ s/^.*[\n|\r]+//mx;
      $get =~ s/^.*[\n|\r]+(\w[^\n|^\r]*)$/$1/mx;
      $get =~ s/^\s*|\s*$//gsmx;
      $self->{log}->Log( $self->{lang}{mess8}.'"'.$get.'"', 1, 5 );
      return $get;
    }
    return -1;
  }
  return;
}

# #######################
# BOUCLE SEND + GET
# #######################
sub boucle_get
{
  my $self = shift;
  my ($get, $get2, $line);

  if (defined $self->{telnet})
  {
     foreach $line (@{$_[0]}) {
       $self->send($line);
       sleep $_[1] if (defined $_[1]);
       $get = $self->{telnet}->get();
       if ($get) {
        $self->{lines} .= $get;
        $get2 .= $get;
       }
    }
    undef $get;
    return $get2;
  }
  return;
}

# #######################
# FUNCTION WAIT
# #######################
sub wait_for
{
  my $self = shift;
  my ($prematch, $match);

  if (defined $self->{telnet})
  {
    $self->{log}->Log( $self->{lang}{mess7}.$_[0], 1, 5 );
    ($prematch, $match) = $self->{telnet}->waitfor('/'.$_[0].'/');
    if (defined $match) {
      if (!defined $prematch) { $prematch = ""; }
      $self->{lines} .= $prematch.$match;
      $self->{return} .= $prematch.$match;
      $prematch = $match = undef;
      return $self->{return};
    }
    return (-1);
  }
}

# #######################
# SEND CHAR
# #######################
sub send_char
{
  my $self = shift;
  my $nbr = $_[3];
  my ($prematch, $match);
  $self->{return} = '';

  if (defined $self->{telnet})
  {
    while ($nbr != 0) {
      $self->{log}->Log( $self->{lang}{mess7}.$_[0], 1, 5 );
      ($prematch, $match) = $self->{telnet}->waitfor('/'.$_[0].'/');
      if (defined $match) {
        if (!defined $prematch) { $prematch = ""; }
        if (defined $_[4] && ($_[4] == 1)) { $match = ''; }
        $self->{lines} .= $prematch.$match;
        $self->{return} .= $prematch.$match;
        $self->{log}->Log( $self->{lang}{mess5}.'\"'.$_[1].'\"', 1, 5 );
        $self->send_as_bytes($_[1]);
      }
      else {
        if (!defined $prematch) { $prematch = ''; }
        if (defined $_[4] && ($_[4] == 1)) { $match = ''; }
        $self->{lines} .= $prematch;
        $self->{return} .= $prematch;
        last;
      }
      $nbr--;
    }
    $prematch = $match = undef;
    return $self->wait_for($_[2]);
  }
  return (-1);
}

# #######################
# SEND BYTES
# #######################
sub send_as_bytes
{
	my $self  = shift;

	if (defined $_[0]) {
    my $length     = length $_[0];
	  my $pack_arg   = 'H' . $length;
	  my $byte_input = pack  $pack_arg, $_[0];
	  $self->{telnet}->put($byte_input);
	}
	return;
}

# #######################
# FUNCTION PROMPT
# #######################
sub calcul_prompt
{
  my $self = shift;
  my $result;
  $self->{return} = '';

  if (!defined $_[1]) {
    $self->wait_for($_[0]);
    $result = $self->{return};
  }
  else {
    $result = $_[1];
  }
  $result =~ s/^.*[\n|\r]+(\w[^\n|^\r]*)$/$1/smx;
  $result = quotemeta $result;
  $result =~ s/^(\S+)(\S{2})$/$1\\S*$2/smx;
  $result = $result.'\s*';
  $self->{log}->Log( $self->{lang}{mess6}.$result, 1, 5 );
  return $result;
}

# #######################
# FUNCTION DISCONNECT
# #######################
sub disconnect
{
  my $self = shift;

  if (defined($self->{telnet}))
  {
    $self->{log}->Log( $self->{lang}{mess3}.$self->{lines}, 1, 5 );
    $self->{telnet}->close;
    $self->{log}->Log( $self->{lang}{mess4}.$self->{HOST}, 1, 5 );
  }
  return;
}

# #######################
# DESTROY OBJECT
# #######################
sub DESTROY {
    my $self = shift;
    return;
}
1;
__END__
